
type ChannelCallback = (...args: any) => any;
type ChannelCallbacks = Array<ChannelCallback>;

/**
 * 事件
 * @example
 * // 事件订阅
 * Event.subscribe('aaa', (text: string)=>{
 *  console.log(text);
 * });
 * // 事件发布
 * Event.publish('aaa', 'hello');
 * 
 * 
 */
export class Event {


  private _channelsMap = new Map<string, ChannelCallbacks>();

  /**
   * 订阅
   *
   * @param {string} eventName 事件名称
   * @param {function} callbackFn 回调函数
   */
  public subscribe(eventName: string, callbackFn: ChannelCallback): ChannelCallbacks {
    const callbacks = this._channelsMap.get(eventName) ?? [];
    const hasFn = !!~callbacks.findIndex(cb => cb === callbackFn);
    if (!hasFn) {
      callbacks.push(callbackFn);
      this._channelsMap.set(eventName, callbacks);
    }
    return callbacks;
  }

  /**
   * 取消订阅
   *
   * @param {string} eventName 事件名称
   *
   * @return true if a handler was removed
   */
  unsubscribe(eventName: string): boolean {
    return this._channelsMap.delete(eventName);
  }

  /**
   * 销毁
   */
  destroy() {
    this._channelsMap.clear();
  }

  /**
   * 发布
   *
   * @param {string} eventName 事件名称
   * @param {any} eventData 事件发送数据
   */
  publish(eventName: string, ...eventData: any): ChannelCallbacks {
    const callbacks = this._channelsMap.get(eventName) ?? [];
    callbacks.forEach(cb => {
      cb(...eventData);
    })
    return callbacks;
  }
}
